package com.hy.service.impl;

import com.hy.bean.*;
import com.hy.dao.*;
import com.hy.dao.impl.*;
import com.hy.dto.OutAddDto;
import com.hy.exception.BizException;
import com.hy.service.OutstoretableService;
import com.hy.utils.DBManager;
import com.hy.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.DbUtils;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class OutstoretableServiceImpl implements OutstoretableService {
    private final OutstoretableDao outstoretableDao = new OutstoretableDaoImpl();
    private final OrderstableDao orderstableDao = new OrderstableDaoImpl();
    private final OrdersPartstableDao ordersPartstableDao = new OrdersPartstableDaoImpl();

    private final CarpartstableDao carpartstableDao = new CarpartstableDaoImpl();

    private final BuytableDao buytableDao = new BuytableDaoImpl();

    private final BuyParttableDao buyParttableDao = new BuyParttableDaoImpl();

    private final OutsotreOrdertableDao outsotreOrdertableDao = new OutsotreOrdertableDaoImpl();

    @Override
    public PageResult pagingQuery(Integer currPage, Integer pageSize, Outstoretable outstoretable) {
        List<OutsotreVo> outsotreVos = outstoretableDao.queryAllByLimit(currPage, pageSize, outstoretable);
        long count = outstoretableDao.count(outstoretable);
        return new PageResult<>(outsotreVos, count, currPage, pageSize);
    }

    @Override
    public RespBean addOutstoretable(OutAddDto outAddDto) {
        Connection connection = null;
        Boolean flag = false;
        Integer buytableId = 0;
        try {
            connection = DBManager.getConnection();
            connection.setAutoCommit(false);
            //拿到订单
            OrderstableVo orderstableVo = orderstableDao.selectOrdersParts(outAddDto.getId());

            //创建出库对象
            Outstoretable outstoretable = new Outstoretable(null, Integer.parseInt(randomGenerate()), orderstableVo.getId(), outAddDto.getNameId(), new Date(), orderstableVo.getClientId(), outAddDto.getRemark());
            //添加出库返回主键
            Integer outstoreId = outstoretableDao.insert(connection, outstoretable);

            //订单中间表
            List<OrdersPartstableVo> ordersPartstables = orderstableVo.getChild();
            int i = 0;
            for (OrdersPartstableVo ordersPartstable : ordersPartstables) {
                //判断是否交付完成如果不相等表示未交付完成
                if (ordersPartstable.getPaycount() != ordersPartstable.getOrdercount()) {
                    //订购数量 大于 库存数量则库存有多少交多少并创建采购
                    if (ordersPartstable.getOrdercount() > ordersPartstable.getPartStore()) {
                        //则库存有多少交多少
                        OutsotreOrdertable outsotreOrdertable = new OutsotreOrdertable(null, outstoreId, ordersPartstable.getPartstableId(), ordersPartstable.getPartStore());
                        //添加出库中间表
                        int outsotreOrderId_notEnough = outsotreOrdertableDao.insert(connection, outsotreOrdertable);

                        //修改订单中间表的已付数量
                        int updatePayCountById_notEnough = ordersPartstableDao.updatePayCountById(connection, ordersPartstable.getId(), ordersPartstable.getPartStore(), ordersPartstable.getOrdercount() - ordersPartstable.getPartStore());

                        //修改订单的缺货状态
                        int updateIsHaveById = orderstableDao.updateIsHaveById(connection, orderstableVo.getId(), 1);

                        //修改库存数量 0表示没有
                        int updatePartStoreId_notEnough = carpartstableDao.updatePartStore(connection, 0, ordersPartstable.getPartstableId());

                        /*//创建采购表
                        Buytable buytable = new Buytable(null, Integer.parseInt(randomGenerate()), null, null, null, outAddDto.getName(), new Date(), null, null, null, null, null, null, null, null, null, "2", null);
                        //添加采购
                        int buytableId_notEnough = buytableDao.insert(connection, buytable);*/
                    } else {
                        //剩余库存量
                        Integer num = ordersPartstable.getPartStore() - ordersPartstable.getOrdercount();
                        //出库中间表
                        OutsotreOrdertable
                                outsotreOrdertable = new OutsotreOrdertable(null, outstoreId, ordersPartstable.getPartstableId(), ordersPartstable.getOrdercount());
                        int outsotreOrderId_sufficient = outsotreOrdertableDao.insert(connection, outsotreOrdertable);
                        //修改订单中间表的已付数量和订单数方便第二次提交(订单数减已付数量)
                        int updatePayCountById_sufficient = ordersPartstableDao.updatePayCountById(connection, ordersPartstable.getId(), ordersPartstable.getOrdercount(), ordersPartstable.getOrdercount() - ordersPartstable.getOrdercount());

                        //修改库存数量
                        int updatePartStore_sufficient = carpartstableDao.updatePartStoreOut(connection, ordersPartstable.getPartstableId(), num);

                        //用来表示完成状态
                        i += 1;
                    }
                } else {
                    i += 1;
                }

            }
            if (i == ordersPartstables.size()) {
                //修改订单的完成状态1表示未完成
                int updateOkstatusById = orderstableDao.updateOkstatusById(connection, orderstableVo.getId(), 1);
            }
            //表示出库完成
            connection.commit();

            createBuytable(outAddDto, buytableId, connection);
            connection.commit();
            flag = true;
        } catch (Exception e) {
            try {
                connection.rollback();
                flag = false;
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new BizException("添加出库失败", e);
        } finally {
            try {
                DbUtils.close(connection);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        return flag ? RespBean.success("出库成功") : RespBean.error("出库失败");
    }

    //添加采购
    private void createBuytable(OutAddDto outAddDto, Integer buytableId, Connection connection)  {
        //采购
        List<Carpartstable> carpartstables = whetherOutOfStock();//查看库存不够的
        List<BuyParttable> buyParttables = buyParttableDao.queryAll();
        //如果有就创建采购订单
        if (carpartstables.size() > 0) {
            //根据当前时间查询 当前时间是否有采购
            Buytable buytableIsNull = buytableDao.selectByRequestTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            if (buytableIsNull == null) {
                //创建采购表
                Buytable buytable = new Buytable(null, Integer.parseInt(randomGenerate()), null, null, null, outAddDto.getName(), new Date(), null, null, null, null, null, null, null, null, null, "2", "库存不足");
                //添加采购
                buytableId = buytableDao.insert(connection, buytable);
            } else {
                buytableId = buytableIsNull.getId();
            }
        }
        for (Carpartstable carpartstable : carpartstables) {
            //判断采购中间表中是否有这个零件的采购
            if (!buyParttables.stream().anyMatch(buyParttable -> buyParttable.getParttableId() == carpartstable.getId())) {
                //创建采购中间表
                BuyParttable buyParttable = new BuyParttable(null, buytableId, carpartstable.getId(), 500, 0, 0, 0.0, 0.0);
                buyParttable.setTotalprice((double) (carpartstable.getCostprice() * buyParttable.getBuycount()));
                //添加采购中间表
                int buyParttableId_notEnough = buyParttableDao.insert(connection, buyParttable);
            } else {
                /**
                 * 如果存在 则修改数量
                 * 数量计算：
                 * 1.通过零件id查询这个零件的采购数量
                 * 2.查询到的零件数量+库存数=已加的库存数
                 * 3.如果库存数量大于最小的库存数量
                 */
                //零件id查询这个零件的采购数量
                BuyParttable selectByParttableId = buyParttableDao.selectByParttableId(carpartstable.getId(), buytableId);
                //查询到的零件数量+库存数=已加的库存数
                if ((carpartstable.getPartstore() + selectByParttableId.getBuycount()) > carpartstable.getPartminstore()) {
                    //修改采购中间表的数量
                    int updateBuycount = buyParttableDao.updateBuycount(connection, selectByParttableId.getId(), selectByParttableId.getBuycount() + 500);
                }
            }
        }
    }

    /***
     * 是否超库存
     * @return
     */
    private List<Carpartstable> whetherOutOfStock() {
        List<Carpartstable> outOfStock = new ArrayList<>();
        List<Carpartstable> carpartstableList = carpartstableDao.select();
        for (Carpartstable carpartstable : carpartstableList) {
            if (carpartstable.getPartstore() <= carpartstable.getPartminstore())
                outOfStock.add(carpartstable);
        }
        return outOfStock;
    }

    private String randomGenerate() {
        String datastr = "";
        Integer randomNumber = 0;
        Integer v = (int) (Math.floor(Math.random() * (10 - 5 + 1)) + 5);
        for (int i = 0; i < v; i++) {
            if (i % 2 == 0) {
                randomNumber = (int) Math.floor(Math.random() * 10);
                datastr += randomNumber + "";
            } else {
                randomNumber = (int) Math.floor(Math.random() * 5);
                datastr += randomNumber + "";
            }
        }
        return datastr;
    }
}